package postgres;


public class Encoder {
	
	private byte[] buffer;
	private int index;
	private int lengthPosition;
	private int lengthSize;
	private int length;
	
	public Encoder() {
		buffer = new byte[100];
		index = 0;
		lengthPosition = -1;
	}

	public void pushInt(int size, int value) {
		for (int i = size/8-1; i >= 0; --i) {
			pushByte((value>>(i*8)) & 0xFF);
		}
	}
	
	public void pushInts(int size, int[] values) {
		for (int v : values) {
			pushInt(size, v);
		}
	}

	public void pushString(String str) {
		for (int i = 0; i < str.length(); ++i) {
			pushByte(str.charAt(i));
		}
		pushByte(0);
	}

	public void pushByte(int value) {
		if (index >= buffer.length) {
			byte[] newBuffer = new byte[buffer.length*2];
			System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
			buffer = newBuffer;
		}
		buffer[index++] = (byte)value;
	}
	
	public void pushBytes(byte[] values) {
		for (byte v : values) {
			pushByte(v);
		}
	}

	public void pushLength(int size) {
		lengthPosition = index;
		lengthSize = size;
		pushInt(size, 0);
	}

	public void finishMessage() {
		length = index;
		if (lengthPosition >= 0) {
			index = lengthPosition;
			pushInt(lengthSize, length - lengthPosition);
		}
	}

	private byte[] getBuffer() {
		byte[] newBuffer = new byte[length];
		System.arraycopy(buffer, 0, newBuffer, 0, length);
		return newBuffer;
	}

	public byte[] encode(Message mes) {
		index = 0;
		lengthPosition = -1;
		mes.encodeOn(this);
		return getBuffer();
	}
	
}
